package cn.gailvlun.gll.pay;

import android.app.Activity;

import com.alipay.sdk.app.PayTask;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import java.lang.ref.WeakReference;
import java.util.Map;

import io.reactivex.Single;
import io.reactivex.SingleEmitter;
import io.reactivex.SingleObserver;
import io.reactivex.SingleOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class UniPay {
    public static String wechatAppId;

    public static void init(String wechatAppId) {
        UniPay.wechatAppId = wechatAppId;
    }

    private WeakReference<Activity> context;
    private UniPayMethod uniPayMethod;
    private UniPayListener uniPayListener;

    private IWXAPI iwxapi;

    public UniPay(Builder builder) {
        context = builder.context;
        uniPayMethod = builder.uniPayMethod;
        uniPayListener = builder.uniPayListener;

        if (uniPayMethod == UniPayMethod.wechatPay) {
            iwxapi = WXAPIFactory.createWXAPI(context.get(), wechatAppId, false);
            iwxapi.registerApp(wechatAppId);

            WXPayEntryActivity.uniPayListener = uniPayListener;
        }
    }

    public boolean isAppInstalled() {
        switch (uniPayMethod) {
            case wechatPay:
                return iwxapi.isWXAppInstalled();
            default:
                return true;
        }
    }

    public void pay(final String alipayReq) {
        Single.create(new SingleOnSubscribe<Map<String, String>>() {
            @Override
            public void subscribe(SingleEmitter<Map<String, String>> emitter) throws Exception {
                PayTask alipay = new PayTask(context.get());
                emitter.onSuccess(alipay.payV2(alipayReq, true));
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SingleObserver<Map<String, String>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onSuccess(Map<String, String> stringStringMap) {
                        AliPayResult aliPayResult = new AliPayResult(stringStringMap);
                        switch (aliPayResult.getResultStatus()) {
                            case "9000": {
                                uniPayListener.onSuccess();
                                break;
                            }
                            case "4000": {
                                uniPayListener.onError("订单支付失败");
                                break;
                            }
                            case "5000": {
                                uniPayListener.onError("重复请求");
                                break;
                            }
                            case "6001": {
                                uniPayListener.onError("用户中途取消");
                                break;
                            }
                            case "6002": {
                                uniPayListener.onError("网络连接出错");
                                break;
                            }
                            default: {
                                uniPayListener.onError("其他错误");
                            }
                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }
                });
    }

    public void pay(PayReq payReq) {
        iwxapi.sendReq(payReq);
    }

    public static class Builder {
        private WeakReference<Activity> context;
        private UniPayMethod uniPayMethod;
        private UniPayListener uniPayListener;

        public Builder(Activity context) {
            this.context = new WeakReference<>(context);
        }

        public Builder method(UniPayMethod uniPayMethod) {
            this.uniPayMethod = uniPayMethod;
            return this;
        }

        public Builder onListener(UniPayListener uniPayListener) {
            this.uniPayListener = uniPayListener;
            return this;
        }

        public UniPay build() {
            return new UniPay(this);
        }
    }
}
